from fastapi import APIRouter, HTTPException, Depends, File, UploadFile, Query, BackgroundTasks
from typing import List, Optional, Dict, Any
import asyncio
import uuid
from datetime import datetime, date
import os
import tempfile
import shutil

from ..models.audit_models import (
    AuditRequest, AuditResult, AuditStandard, BatchAuditRequest,
    AuditRequestResponse, AuditResultResponse, AuditHistoryResponse,
    AuditStandardResponse, AuditStatsResponse, BatchAuditResponse,
    AuditDecision, AuditorType
)
from ..models.base import BaseResponse, ErrorResponse
from ..modules.classroom_audit import AuditWorkflow, AuditStrategy, AuditWorkflowManager, AuditWorkflowConfig
from ..modules.custom_standards import StandardManager
from ..utils.logger import get_logger

router = APIRouter(prefix="/audit", tags=["classroom-audit"])
logger = get_logger(__name__)

# 全局工作流管理器
workflow_manager = AuditWorkflowManager()


def get_audit_workflow() -> AuditWorkflow:
    """获取审核工作流实例."""
    return workflow_manager.get_workflow()


@router.post("/submit", response_model=AuditResultResponse)
async def submit_audit_request(
    request: AuditRequest,
    strategy: AuditStrategy = Query(AuditStrategy.STANDARD, description="审核策略"),
    standard_id: Optional[str] = Query(None, description="使用的审核标准ID"),
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    提交单个审核请求
    
    - **request**: 审核请求数据
    - **strategy**: 审核策略 (fast/standard/strict/ai_only)
    - **standard_id**: 可选的自定义审核标准ID
    """
    try:
        logger.info(f"收到审核请求: {request.request_id}, 策略: {strategy}")
        
        # 执行审核
        result = await workflow.audit_request(request, strategy, standard_id)
        
        # 构建响应
        recommendations = []
        if result.ai_analysis and result.ai_analysis.risk_assessment:
            mitigation = result.ai_analysis.risk_assessment.get("mitigation_suggestions", [])
            recommendations.extend(mitigation[:3])  # 最多显示3个建议
        
        return AuditResultResponse(
            message=f"审核完成，决策: {result.decision.value}",
            result=result,
            recommendations=recommendations
        )
        
    except Exception as e:
        logger.error(f"审核请求处理失败: {str(e)}")
        raise HTTPException(
            status_code=500,
            detail=f"审核处理失败: {str(e)}"
        )


@router.post("/submit-with-files", response_model=AuditResultResponse)
async def submit_audit_with_files(
    applicant_name: str,
    applicant_id: str,
    classroom_id: str,
    start_time: datetime,
    end_time: datetime,
    usage_purpose: str,
    participants_count: int,
    strategy: AuditStrategy = Query(AuditStrategy.STANDARD),
    files: List[UploadFile] = File(default=[]),
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    提交带文件的审核请求
    
    支持上传多个文件作为申请材料
    """
    try:
        # 处理上传的文件
        documents = []
        temp_files = []
        
        for file in files:
            if file.size > 10 * 1024 * 1024:  # 10MB限制
                raise HTTPException(status_code=413, detail=f"文件 {file.filename} 过大")
            
            # 保存到临时文件
            with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{file.filename}") as tmp_file:
                content = await file.read()
                tmp_file.write(content)
                temp_files.append(tmp_file.name)
                
                documents.append({
                    "id": str(uuid.uuid4()),
                    "filename": file.filename,
                    "file_path": tmp_file.name,
                    "mime_type": file.content_type,
                    "size": len(content)
                })
        
        # 构建审核请求
        audit_request = AuditRequest(
            applicant_info={
                "applicant_name": applicant_name,
                "applicant_id": applicant_id,
                "type": "unknown"  # 可以从数据库查询
            },
            classroom_id=classroom_id,
            start_time=start_time,
            end_time=end_time,
            usage_purpose=usage_purpose,
            participants_count=participants_count,
            documents=documents
        )
        
        # 执行审核
        result = await workflow.audit_request(audit_request, strategy)
        
        # 清理临时文件
        for temp_file in temp_files:
            try:
                os.unlink(temp_file)
            except:
                pass
        
        return AuditResultResponse(
            message=f"审核完成，决策: {result.decision.value}",
            result=result
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"文件审核请求处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/batch", response_model=BatchAuditResponse)
async def submit_batch_audit(
    batch_request: BatchAuditRequest,
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    提交批量审核请求
    
    - **batch_request**: 包含多个审核请求的批量请求
    """
    try:
        logger.info(f"收到批量审核请求，共 {len(batch_request.requests)} 个")
        
        # 执行批量审核
        results = await workflow.batch_audit(
            batch_request.requests,
            AuditStrategy.STANDARD,  # 默认使用标准策略
            batch_request.standard_id,
            max_concurrent=3  # 限制并发数
        )
        
        # 统计结果
        successful_count = len([r for r in results if r.decision != AuditDecision.PENDING])
        failed_count = len(results) - successful_count
        
        # 收集错误信息
        errors = []
        for i, result in enumerate(results):
            if result.metadata and "error" in result.metadata:
                errors.append({
                    "request_index": i,
                    "error": result.metadata["error"]
                })
        
        return BatchAuditResponse(
            message=f"批量审核完成，成功: {successful_count}, 失败: {failed_count}",
            batch_id=str(uuid.uuid4()),
            total_requests=len(batch_request.requests),
            successful_count=successful_count,
            failed_count=failed_count,
            results=results,
            errors=errors if errors else None
        )
        
    except Exception as e:
        logger.error(f"批量审核失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/status/{request_id}", response_model=BaseResponse)
async def get_audit_status(
    request_id: str,
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    查询审核状态
    
    - **request_id**: 审核请求ID
    """
    try:
        status = workflow.get_audit_status(request_id)
        
        if not status:
            raise HTTPException(status_code=404, detail="审核请求未找到")
        
        return BaseResponse(
            message="状态查询成功",
            data=status
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"状态查询失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/history", response_model=AuditHistoryResponse)
async def get_audit_history(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    status: Optional[str] = Query(None, description="筛选状态"),
    classroom_id: Optional[str] = Query(None, description="筛选教室"),
    date_from: Optional[date] = Query(None, description="开始日期"),
    date_to: Optional[date] = Query(None, description="结束日期")
):
    """
    查询审核历史记录
    
    支持分页和多维度筛选
    """
    try:
        # 这里应该从数据库查询，现在返回模拟数据
        mock_results = []
        
        # 模拟一些审核结果
        for i in range(min(page_size, 5)):
            mock_result = AuditResult(
                request_id=str(uuid.uuid4()),
                decision=AuditDecision.APPROVED if i % 2 == 0 else AuditDecision.REJECTED,
                final_score=75.0 + i * 5,
                confidence_level=0.8,
                reasons=[f"模拟审核原因 {i}"],
                rule_results=[],
                auditor_type=AuditorType.HYBRID,
                processing_time_ms=150.0
            )
            mock_results.append(mock_result)
        
        total_count = 50  # 模拟总数
        
        return AuditHistoryResponse(
            message="历史记录查询成功",
            total_count=total_count,
            page_size=page_size,
            current_page=page,
            results=mock_results
        )
        
    except Exception as e:
        logger.error(f"历史查询失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/standards", response_model=AuditStandardResponse)
async def list_audit_standards(
    include_inactive: bool = Query(False, description="包含未激活的标准")
):
    """
    列出所有审核标准
    
    - **include_inactive**: 是否包含未激活的标准
    """
    try:
        manager = StandardManager()
        standards = manager.list_standards(include_inactive)
        
        return AuditStandardResponse(
            message=f"查询到 {len(standards)} 个审核标准",
            standards=standards
        )
        
    except Exception as e:
        logger.error(f"标准列表查询失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/standards", response_model=BaseResponse)
async def create_audit_standard(
    standard_data: Dict[str, Any]
):
    """
    创建新的审核标准
    
    - **standard_data**: 审核标准JSON数据
    """
    try:
        manager = StandardManager()
        standard = manager.create_standard(standard_data)
        
        return BaseResponse(
            message=f"审核标准创建成功: {standard.name}",
            data={"standard_id": standard.standard_id}
        )
        
    except Exception as e:
        logger.error(f"标准创建失败: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))


@router.put("/standards/{standard_id}", response_model=BaseResponse)
async def update_audit_standard(
    standard_id: str,
    updates: Dict[str, Any]
):
    """
    更新审核标准
    
    - **standard_id**: 标准ID
    - **updates**: 更新数据
    """
    try:
        manager = StandardManager()
        standard = manager.update_standard(standard_id, updates)
        
        return BaseResponse(
            message=f"审核标准更新成功: {standard.name}"
        )
        
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error(f"标准更新失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/standards/{standard_id}", response_model=BaseResponse)
async def delete_audit_standard(
    standard_id: str
):
    """
    删除审核标准
    
    - **standard_id**: 标准ID
    """
    try:
        manager = StandardManager()
        success = manager.delete_standard(standard_id)
        
        if not success:
            raise HTTPException(status_code=404, detail="审核标准未找到")
        
        return BaseResponse(
            message="审核标准删除成功"
        )
        
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"标准删除失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/stats", response_model=AuditStatsResponse)
async def get_audit_statistics(
    date_from: Optional[date] = Query(None, description="开始日期"),
    date_to: Optional[date] = Query(None, description="结束日期")
):
    """
    获取审核统计信息
    
    - **date_from**: 统计开始日期
    - **date_to**: 统计结束日期
    """
    try:
        # 模拟统计数据
        stats = {
            "total_requests": 156,
            "approved_count": 98,
            "rejected_count": 32,
            "pending_count": 26,
            "average_processing_time_ms": 1250.5,
            "approval_rate": 0.628
        }
        
        return AuditStatsResponse(
            message="统计信息查询成功",
            **stats
        )
        
    except Exception as e:
        logger.error(f"统计查询失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/standards/{standard_id}/duplicate", response_model=BaseResponse)
async def duplicate_audit_standard(
    standard_id: str,
    new_name: str
):
    """
    复制审核标准
    
    - **standard_id**: 源标准ID  
    - **new_name**: 新标准名称
    """
    try:
        manager = StandardManager()
        new_standard = manager.duplicate_standard(standard_id, new_name)
        
        return BaseResponse(
            message=f"审核标准复制成功: {new_standard.name}",
            data={"new_standard_id": new_standard.standard_id}
        )
        
    except Exception as e:
        logger.error(f"标准复制失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/workflow/status", response_model=BaseResponse)
async def get_workflow_status(
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    获取工作流状态信息
    """
    try:
        active_count = workflow.get_active_audits_count()
        
        return BaseResponse(
            message="工作流状态查询成功",
            data={
                "active_audits_count": active_count,
                "workflow_initialized": True,
                "ai_enabled": workflow.config.enable_ai_analysis,
                "rules_enabled": workflow.config.enable_rule_engine
            }
        )
        
    except Exception as e:
        logger.error(f"工作流状态查询失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/workflow/configure", response_model=BaseResponse)
async def configure_workflow(
    ai_enabled: bool = Query(True),
    rules_enabled: bool = Query(True),
    parallel_processing: bool = Query(True),
    max_processing_time: int = Query(300)
):
    """
    配置审核工作流参数
    """
    try:
        config = AuditWorkflowConfig()
        config.enable_ai_analysis = ai_enabled
        config.enable_rule_engine = rules_enabled
        config.parallel_processing = parallel_processing
        config.max_processing_time_seconds = max_processing_time
        
        # 重新配置工作流
        workflow_manager.reconfigure_workflow(config)
        
        return BaseResponse(
            message="工作流配置更新成功"
        )
        
    except Exception as e:
        logger.error(f"工作流配置失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/workflow/audits/{request_id}", response_model=BaseResponse)
async def cancel_audit(
    request_id: str,
    workflow: AuditWorkflow = Depends(get_audit_workflow)
):
    """
    取消正在进行的审核
    
    - **request_id**: 要取消的审核请求ID
    """
    try:
        success = await workflow.cancel_audit(request_id)
        
        if not success:
            raise HTTPException(status_code=404, detail="审核请求未找到或已完成")
        
        return BaseResponse(
            message="审核已取消"
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"取消审核失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/test", response_model=AuditResultResponse)
async def test_audit_system():
    """
    测试审核系统 - 提交一个示例请求
    """
    try:
        # 创建测试请求
        test_request = AuditRequest(
            applicant_info={
                "applicant_name": "张教授",
                "applicant_id": "T001", 
                "type": "teacher"
            },
            classroom_id="A101",
            start_time=datetime(2024, 12, 20, 14, 0),
            end_time=datetime(2024, 12, 20, 16, 0),
            usage_purpose="学术研讨会，讨论人工智能在教育中的应用",
            participants_count=25,
            equipment_needs=["投影仪", "音响", "话筒"]
        )
        
        # 获取工作流并执行审核
        workflow = get_audit_workflow()
        result = await workflow.audit_request(test_request, AuditStrategy.STANDARD)
        
        return AuditResultResponse(
            message=f"测试审核完成，决策: {result.decision.value}",
            result=result
        )
        
    except Exception as e:
        logger.error(f"测试审核失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))